package org.danger.t7.common.meters;

import javax.servlet.DispatcherType;

import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.MeterRegistry;
import org.danger.t7.common.meters.http.HttpMetricFilter;
import org.danger.t7.common.meters.http.WebPrometheusInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter;
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * metrics 自动配置
 */
@Configuration
@ComponentScan
public class PrometheusConf implements WebMvcConfigurer {

    @Value("${spring.application.name}")
    private String application;

    @Autowired
    private Environment environment;

    @Autowired
    private  MetricsProperties properties;


    /**
     * common tags
     *
     * @return .
     */
//    @Bean
//    public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
//        return (registry) -> registry.config().commonTags("application", application);
//    }
    @Bean
    MeterRegistryCustomizer<MeterRegistry> configurer(@Value("${spring.application.name}") String applicationName) {
        return new MeterRegistryCustomizer<MeterRegistry>() {
            @Override
            public void customize(MeterRegistry registry) {
                registry.config().commonTags("application", applicationName);
            }
        };
    }

//    @Bean
//    public TimedAspect timedAspect(MeterRegistry meter) {
//        return new TimedAspect(meter);
//    }

//    @Bean
//    public HandlerInterceptor prometheusInterceptor() {
//        return new WebPrometheusInterceptor();
//    }
//
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(prometheusInterceptor()).addPathPatterns("/**");
//    }

//    /**
//     * .
//     *
//     * @return .
//     */
//    @Bean(name = "httpMetricFilter")
//    public FilterRegistrationBean<HttpMetricFilter> httpMetricFilter(MeterRegistry meter) {
//        FilterRegistrationBean<HttpMetricFilter> filterRegistrationBean = new FilterRegistrationBean<>();
//        filterRegistrationBean.setFilter(new HttpMetricFilter(meter));
//        filterRegistrationBean.addUrlPatterns("/*");
//        filterRegistrationBean.setName("httpMetricFilter");
//        filterRegistrationBean.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE + 2); //order的数值越小 则优先级越高
//        return filterRegistrationBean;
//    }


    @Bean(name = "webMvcMetricsFilter")
    public FilterRegistrationBean<WebMvcMetricsFilter> webMvcMetricsFilter(MeterRegistry registry,
                                                                           WebMvcTagsProvider tagsProvider) {
        MetricsProperties.Web.Server.ServerRequest request = this.properties.getWeb().getServer().getRequest();
        WebMvcMetricsFilter filter = new WebMvcMetricsFilter(registry, tagsProvider, request.getMetricName(),
                request.getAutotime());
        FilterRegistrationBean<WebMvcMetricsFilter> registration = new FilterRegistrationBean<>(filter);
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
        registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);
        return registration;
    }
//    @Bean
//    MeterRegistryCustomizer metricsCommonTag2s() {
//
//        return registry -> {
//            registry.config().meterFilter(
//                    new MeterFilter() {
//                        @Override
//                        public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
//                            if (id.getType() == Meter.Type.TIMER && id.getName().matches("^(http|hystrix){1}.*")) {
//                                return DistributionStatisticConfig.builder()
//                                        .percentilesHistogram(true)
//                                        .percentiles(0.5, 0.90, 0.95, 0.99)
////                    //设置时间范围
////                    .minimumExpectedValue(Duration.ofMillis(400).toNanos())
////                    .maximumExpectedValue(Duration.ofMillis(800).toNanos())
////                    .sla(Duration.ofMillis(50).toNanos(),
////                        Duration.ofMillis(100).toNanos(),
////                        Duration.ofMillis(200).toNanos(),
////                        Duration.ofSeconds(1).toNanos(),
////                        Duration.ofSeconds(5).toNanos()
//                                        .build()
//                                        .merge(config);
//                            } else {
//                                return config;
//                            }
//                        }
//                    });
//        };
//    }

}
